﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


using System.Collections;
using System.Diagnostics;
using NPlot;

using CStock;


namespace CGraph
{
    public partial class ChartWindow : Form , IChartWindow
    {
        private double penWidth;
        protected IProgramContext programContext;
        private string symbol;
        protected IDataItem dataItem;
        private int scrollSize;
        IList<ChartControl> charts;
        public ChartWindow()
        {
            try
            {
                InitializeComponent();
                penWidth = 1.0f;
                CreateChartList();
                FillComboBoxPeriod();
                this.comboIntradayQuotes.Visible = false;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in constructor of ChartWindow: " + ex.Message);
            }
           
            //this.Initialize_ChartData();

        }
        public void FillComboBoxPeriod()
		{
			ChartPeriods cp = new ChartPeriods();
			Type typ = cp.GetType();

			System.Array arr = ChartPeriods.GetValues(typ);
			for(int i = 0; i < arr.GetLength(0); i++)
			{
				string str = arr.GetValue(i).ToString();
				str = str.Remove(0,1);
                switch (str)
                {

                    case ("30"):
                        {
                            this.comboBoxPeriod.Items.Add("1 Month");
                            break;
                        }
                    case ("60"):
                        {
                            this.comboBoxPeriod.Items.Add("2 Month");
                            break;
                        }
                    case ("90"):
                        {
                            this.comboBoxPeriod.Items.Add("3 Month");
                            break;
                        }
                    case ("180"):
                        {
                            this.comboBoxPeriod.Items.Add("6 Month");
                            break;
                        }
                    case ("365"):
                        {
                            this.comboBoxPeriod.Items.Add("1 Year");
                            break;
                        }
                    case ("730"):
                        {
                            this.comboBoxPeriod.Items.Add("2 Years");
                            break;
                        }

                    default:
                        {
                            this.comboBoxPeriod.Items.Add(str);
                            break;
                        }
                }
				
			}

            this.comboBoxPeriod.SelectedIndex = 0;

		}
        private void FillComboBoxIntraday()
        {
            if (this.dataItem != null)
            {
                Debug.Assert(this.dataItem.DataClass.DataClassIntraday != null);
                ArrayList files = this.dataItem.DataClass.DataClassIntraday.GetAllAvailableIntradayFiles();
                //int i = files.GetLength(0);

                if (files != null && files.Count > 0)
                {

                    for (int i = 0; i < files.Count; i++)
                    {
                        System.IO.FileInfo file = files[i] as System.IO.FileInfo;
                        string fileName = CUtil.IOUtil.ExtractNameFromFile(file);
                        this.comboIntradayQuotes.Items.Add(fileName);
                    }
                }
            }

        }
        private bool CheckQuotes(IDataItem di)
        {
            IListQuotes quColl = this.dataItem.DataClass.QuotesChart(this.programContext.Configuration);
            Debug.Assert(quColl != null, "No quote data");

            if (quColl == null)
            {
                //System.Windows.Forms.MessageBox.Show("There is no data for the item selected: " + di.Name);
                Debug.WriteLine("There is no data for the item selected: " + di.Name);
                return false;
            }
            //Debug.Assert(di.DataClass.QuoteCollection.Count > 0,"No quote data");
            if (quColl.Count < 1)
            {
                //System.Windows.Forms.MessageBox.Show("There is no data for the item selected: " + di.Name);
                Debug.WriteLine("There is no data for the item selected: " + di.Name);
                return false;
            }
            return true;
        }
        private void CreateChartList()
        {
            charts = new List<ChartControl>();
            charts.Add(this.chartControl1);
            charts.Add(this.chartControl2);
            charts.Add(this.chartControl3);

        }
        public IList<ChartControl> Charts
        {
            get
            {
                return charts;

                
            }
        }
        private void InitChartControls()
        {
            this.chartControl1.ProgramContext = this.programContext;
            this.chartControl2.ProgramContext = this.programContext;
            this.chartControl3.ProgramContext = this.programContext;
            this.chartControl1.DataItem = this.dataItem;
            this.chartControl2.DataItem = this.dataItem;
            this.chartControl3.DataItem = this.dataItem;

            this.chartControl1.ChartWindow = this;
            this.chartControl2.ChartWindow = this;
            this.chartControl3.ChartWindow = this;

            this.chartControl1.ChartNumber = 0;
            this.chartControl2.ChartNumber = 1;
            this.chartControl3.ChartNumber = 2;

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dh"></param>
        /// <param name="di"></param>
        /// <returns></returns>
        public bool Initialize_ChartData(IProgramContext dh, IDataItem di)
        {
            try
            {
                this.programContext = dh;
                this.dataItem = di;
                //check Chart profile!!

                InitChartControls();
                ProgramContext.Instance.Logfile.WriteTimeSpanLog("       -start Init Chart data : ");
                
                if (!CheckQuotes(di))
                    return false;


                //have to set this because of implementation lack in chart control 
                //this.dataItem.Show100PercentGraph = false;

                this.Text = this.dataItem.DataClass.Name + "; " + this.dataItem.Symbol + " (" + this.dataItem.DataClass.ID + ")";


                toolBarButtonIndicators.Checked = this.dataItem.HideIndicatorsOnChart;
                this.toolBarButton100PercentView.Checked = this.dataItem.Show100PercentGraph;
                this.toolBarButtonCandleStick.Checked = this.dataItem.ChartCandleStick;
               
              
                
                ProgramContext.Instance.Logfile.WriteTimeSpanLog("       -before plot firs: ");

                this.PlotChartControl(this.chartControl1, false);
                this.PlotChartControl(this.chartControl2, false);
                this.PlotChartControl(this.chartControl3, false);

                //ScrollNextControls(false);
                SetChartWidthAndHeight();
                FillComboBoxIntraday();
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error setting data for chart " + ex.Message);
                return false;

            }

        }
        private void SetChartWidthAndHeight()
        {
            int heightMax = Screen.FromControl(this).Bounds.Size.Height;
            int widthMax = Screen.FromControl(this).Bounds.Size.Width;

           
            if (this.dataItem.ChartSizeHeight > 50)
            {
                if (this.dataItem.ChartSizeHeight > heightMax / 1.2)
                {
                    this.dataItem.ChartSizeHeight = Convert.ToInt32(heightMax / 1.2);
                }
               
                    
            }
            if (this.dataItem.ChartSizeHeight == 0)
            {
                this.dataItem.ChartSizeHeight = Convert.ToInt32(heightMax / 1.2);
            }
            if (this.dataItem.ChartSizeWidth > 30)
            {
                if (this.dataItem.ChartSizeWidth > widthMax / 1.2)
                {
                    this.dataItem.ChartSizeWidth = Convert.ToInt32(widthMax / 1.2);
                }
                
            }
            if (this.dataItem.ChartSizeWidth == 0)
            {
                this.dataItem.ChartSizeWidth = Convert.ToInt32(widthMax / 1.2);
            }
            this.Width = this.dataItem.ChartSizeWidth;
            this.Height = this.dataItem.ChartSizeHeight;
            this.splitContainer1.SplitterDistance = (int)(0.5 * (this.Height));

        }
       



        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (this.dataItem != null)
            {
                this.dataItem.ChartSizeHeight = this.Height;
                this.dataItem.ChartSizeWidth = this.Width;
            }
        }
        protected override void OnResize(EventArgs e)
        {

            try
            {
                this.splitContainer1.SplitterDistance = (int)(0.5 * (this.Height));
            }
            catch
            {
            }
            base.OnResize(e);

        }

        #region test

        public void Test_MultiplePlot(DataTable dt)
        {
            ChartControl c = this.chartControl1;
            Test_Plot_SecondChart_Volume(dt);


        }

        private void AddAllInteractions(ChartControl c1)
        {
            c1.PlotSurface.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.HorizontalDrag());
            c1.PlotSurface.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.VerticalDrag());
            c1.PlotSurface.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.AxisDrag(true));
        }
        private void Test_Plot_SecondChart_Volume(DataTable dt)
        {
            ChartControl c2 = this.chartControl1 as ChartControl;

            PointPlot pp = new PointPlot();
            pp.Marker = new Marker(Marker.MarkerType.Square, 0);
            pp.Marker.Pen = new Pen(Color.Red, Convert.ToSingle(penWidth));
            pp.Marker.DropLine = true;
            pp.DataSource = dt;
            pp.AbscissaData = "Date";
            pp.OrdinateData = "Volume";

            c2.PlotSurface.Add(pp);
            c2.PlotSurface.YAxis1.Label = "Volume";
            c2.PlotSurface.YAxis1.LabelOffsetAbsolute = true;
            c2.PlotSurface.YAxis1.LabelOffset = 40;
            c2.PlotSurface.Padding = 5;
            c2.PlotSurface.AddAxesConstraint(new AxesConstraint.AxisPosition(PlotSurface2D.YAxisPosition.Left, 60));

            AddAllInteractions(c2);


        }

        #endregion

      
        /// <summary>
        /// ProgramContext
        /// </summary>
        public IDataItem DataItem
        {
            get
            {

                return this.dataItem;
            }

        }


      
        public string Symbol
        {
            get
            {
                return this.symbol;
            }
            set
            {
                this.symbol = value;
            }
        }


        private bool ResizeChart(IDataPrividerGraph graph1, ChartControl ci)
        {
            try
            {
                graph1.ResetChart();

                graph1.IndexStop = ci.IndexStop;
                graph1.IndexStart = ci.IndexStart;
                if (!graph1.ScrollPlot())
                    this.Close();
                
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in resizing chart: " + ex.Message);
                return false;
            }
        }
        private bool PlotNextControls(bool preserveFirst)
        {
            try
            {

                chartControl2.Plot_Control(false);
                ResizeChart(chartControl2, chartControl1);
                
                chartControl3.Plot_Control(false);
                ResizeChart(chartControl3, chartControl1);
                
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error plotting chart : " + ex.Message);
                return false;
            }
        }
 
        private bool PlotChartControl(ChartControl cc, bool preserveFirst)
        {
            try
            {
                
                //plot first chart:
                
               
                Debug.Assert(cc != null);

                if (preserveFirst)
                {
                    cc.ResetChart();
                    
                    cc.Plot_Control(true);
                    SetChartIndices(this.scrollSize, cc);

                }
                else
                {
                    cc.ResetChart();
                    cc.Plot_Control(true);

                }

                if (this.programContext.Configuration.IntradayModus)
                {
                    if (this.dataItem.ShowIntradayIndicators)
                    {
                        //this.toolBarButtonIndicators.Pushed = true;

                    }
                }


                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error plotting chart : " + ex.Message);
                return false;
            }

        }
       
        public bool RefreshWindow(bool preserveFirst)
        {
            this.PlotChartControl(this.chartControl1, preserveFirst);
            this.PlotChartControl(this.chartControl2, preserveFirst);
            this.PlotChartControl(this.chartControl3, preserveFirst);
            
            return true;

            
        }
        private bool RefreshWindow_OnlyScroll(bool preserveFirst)
        {
            this.PlotChartControl(this.chartControl1, preserveFirst);
            this.PlotChartControl(this.chartControl2, preserveFirst);
            this.PlotChartControl(this.chartControl3, preserveFirst);

           
            return true;


        }

        private IIndicators GetIndicatorCollection()
        {

            IIndicators indColl = null;
            
            if (this.programContext.Configuration.IntradayModus)
            {
                indColl = this.dataItem.DataClass.IndicatorsIntraday;
                
            }
            else
            {
                indColl = this.dataItem.DataClass.IndicatorsChecked;
                
            }
            return indColl;
        }



        #region menus

      
        private void menuIndicatorsChart_Click(object sender, System.EventArgs e)
        {

            ChartControl ci = this.chartControl1 as ChartControl;
            if (this.scrollSize == 0)
            {
                this.scrollSize = ci.IndexMax;
            }


            //if (!this.toolBarButtonIndicators.Pushed)
            //{
            //    this.toolBarButtonIndicators.Pushed = true;
            //    if (this.programContext.Configuration.IntradayModus)
            //    {
            //        this.dataItem.ShowIntradayIndicators = true;

            //    }
            //    else
            //    {
            //        this.dataItem.HideIndicatorsOnChart = true;

            //    }

            //    this.PlotAllControls(true);
            //    ScrollAllCharts();
            //    //IndicatorsShow( );

            //}
        }

        private void menuTradeEvents_Click(object sender, System.EventArgs e)
        {
            try
            {
                ChartControl ci = this.chartControl1;
                ci.PlotEvents(true, this.programContext.Configuration.IntradayModus, programContext);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error showing trade events: " + ex.Message);
            }
        }

        private void menuPrognosisChart_Click(object sender, System.EventArgs e)
        {
            ChartControl ci = this.chartControl1;
            ci.PlotPrognosis(this.programContext.Configuration.IntradayModus);

        }

        private void toolBarChart_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
        {
            try
            {
                ChartControl ci = this.chartControl1;
                if (scrollSize == 0)
                {
                    scrollSize = ci.IndexMax;
                }


                ScrollAllCharts();
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Software Error on action " + ex.Message);

            }

        }
        #endregion





        #region scrolling
        private void comboBoxPeriod_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            ChartControl ci = this.chartControl1;


            switch (this.comboBoxPeriod.SelectedIndex)
            {
                case 0:
                    {
                        ci.IndexStop = ci.IndexMax;
                        SetChartIndices(ci.IndexMax, ci);

                        break;
                    }
                case 1:
                    {

                        SetChartIndices(30, ci);
                        break;
                    }
                case 2:
                    {
                        SetChartIndices(60, ci);
                        break;
                    }
                case 3:
                    {
                        SetChartIndices(90, ci);
                        break;
                    }
                case 4:
                    {
                        SetChartIndices(180, ci);
                        break;
                    }
                case 5:
                    {
                        SetChartIndices(365, ci);
                        break;
                    }
                case 6:
                    {
                        SetChartIndices(730, ci);
                        break;
                    }
            }



        }
        public bool ScrollAllCharts(int indMin, int indMax)
        {

            ScrollAllCharts();
            return true;

        }
        private bool ScrollChart(ChartControl myChartControl)
        {
            ChartControl ci = this.chartControl1 as ChartControl;

            IDataPrividerGraph graph1 = myChartControl as IDataPrividerGraph;

            Debug.Assert(graph1 != null);
            graph1.IndexStop = ci.IndexStop;
            graph1.IndexStart = ci.IndexStart;


            if (!graph1.ScrollPlot())
            {
                this.Close();
                return true;
            }
            return false;

        }
        private void ScrollAllCharts()
        {
            try
            {
                chartControl1.ScrollPlot();

                ScrollChart(this.chartControl2);
                ScrollChart(this.chartControl3);

                


            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error scrolling ", exc.Message);
                this.Close();
            }
        }

        private void SetChartIndices(int scrollS, ChartControl ci)
        {
            try
            {
                this.scrollSize = scrollS;


                if (ci.IndexStop < ci.IndexMax)
                    ci.IndexStop = ci.IndexMax;


                ci.IndexStart = ci.IndexStop - scrollSize;

                if ((ci.IndexStop - ci.IndexStart) < scrollSize)
                {
                    ci.IndexStart -= scrollSize;
                }
                //again:
                if ((ci.IndexStop - ci.IndexStart) < scrollSize)
                {
                    ci.IndexStop = ci.IndexStart + scrollSize;
                }

                ScrollAllCharts();
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error scrolling " + ex.Message);
            }

        }
        private void comboIntradayQuotes_SelectedIndexChanged(object sender, System.EventArgs e)
        {

            //todo: refresh intraday chart
        }
        #endregion

        private void DateUpByOne()
        {
            //			//enter trade mode
            //			if(! this.toolBarButtonUserTrade.Pushed)
            //			{
            //				this.toolBarButtonUserTrade.Pushed = true;
            //				this.mainClass.ProgramContext.Configuration.ProgramMode = ProgramModes.UserTrade;
            //				this.mainClass.DoModeUserTrade(true);
            //
            //				//set the trade simulation collection to the one of the actual portfolio
            //						
            //			}
            //			CTrading.TradeSimulation ts = this.mainClass.ProgramContext.TradeSimulation as CTrading.TradeSimulation;
            //			ts.TradeStepFactory.TradeEvents = this.mainClass.ProgramContext.Portfolio.TradeEvents;
            //
            //			this.mainClass.ProgramContext.UserTradeDateUp(1);
            //			this.mainClass.RefreshChartView();

        }
      
       
        private void toolBarButtonScrollLeftMax_Click(object sender, EventArgs e)
        {
            ScrollChart(0, scrollSize);

         
        }

        private void toolBarButtonScrollLeft_Click(object sender, EventArgs e)
        {
            ScrollChart(this.chartControl1.IndexStart - scrollSize, this.chartControl1.IndexStop - scrollSize);

      

        }

        private void toolBarButtonScrollRight_Click(object sender, EventArgs e)
        {
            ScrollChart(this.chartControl1.IndexStart + scrollSize, this.chartControl1.IndexStop + scrollSize);


           
        }
        private void toolBarButtonScrollRightMax_Click(object sender, EventArgs e)
        {
            ScrollChart(this.chartControl1.IndexMax - scrollSize, this.chartControl1.IndexMax);




        }
        private void ScrollChart(int indMin, int indMax)
        {
            this.chartControl1.IndexStop = indMax;
            this.chartControl1.IndexStart = indMin;

            if ((chartControl1.IndexStop - chartControl1.IndexStart) < scrollSize)
            {
                chartControl1.IndexStart -= scrollSize;
            }
            //again:
            if ((chartControl1.IndexStop - chartControl1.IndexStart) < scrollSize)
            {
                chartControl1.IndexStop = chartControl1.IndexStart + scrollSize;
            }
            ScrollAllCharts();
        }
       

        private void toolBarButtonCandleStick_Click(object sender, EventArgs e)
        {
            this.dataItem.ChartCandleStick = toolBarButtonCandleStick.Checked;
            this.chartControl1.Plot_Control(false);

          

        }

        private void toolBarButtonTradeEvents_Click(object sender, EventArgs e)
        {

            if (!this.chartControl1.PlotEvents(toolBarButtonTradeEvents.Checked, this.programContext.Configuration.IntradayModus, programContext))
            {
                toolBarButtonTradeEvents.Checked = false;
                //b.Pushed = false;

            }

        }

        private void toolBarButton100PercentView_Click(object sender, EventArgs e)
        {
            this.dataItem.Show100PercentGraph = toolBarButton100PercentView.Checked;
            this.dataItem.Serialize();
            this.RefreshWindow_OnlyScroll(true);
        }

        private void comboIntradayQuotes_SelectedIndexChanged_1(object sender, EventArgs e)
        {

        }

        private void comboBoxPeriod1_SelectedIndexChanged(object sender, EventArgs e)
        {

            ChartControl ci = this.chartControl1 as ChartControl;


            switch (this.comboBoxPeriod.SelectedIndex)
            {
                case 0:
                    {
                        ci.IndexStop = ci.IndexMax;
                        SetChartIndices(ci.IndexMax, ci);

                        break;
                    }
                case 1:
                    {

                        SetChartIndices(30, ci);
                        break;
                    }
                case 2:
                    {
                        SetChartIndices(60, ci);
                        break;
                    }
                case 3:
                    {
                        SetChartIndices(90, ci);
                        break;
                    }
                case 4:
                    {
                        SetChartIndices(180, ci);
                        break;
                    }
                case 5:
                    {
                        SetChartIndices(365, ci);
                        break;
                    }
                case 6:
                    {
                        SetChartIndices(730, ci);
                        break;
                    }
            }




        }

        private void toolBarButtonIndicators_Click(object sender, EventArgs e)
        {
            if (this.programContext.Configuration.IntradayModus)
            {
                this.dataItem.ShowIntradayIndicators = toolBarButtonIndicators.Checked;
                this.dataItem.Serialize();

            }
            else
            {
                this.dataItem.HideIndicatorsOnChart = toolBarButtonIndicators.Checked;
                this.dataItem.Serialize();

            }

            this.RefreshWindow(true);
        }

        
    }
    public enum ChartPeriods
    {
        tAll,
        t30,
        t60,
        t90,
        t180,
        t365,
        t730

    }
}
